package com.wzdigit.wms.wms.service.inv.count;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.wzdigit.framework.Shift;
import com.wzdigit.wms.basic.client.response.Result;
import com.wzdigit.wms.basic.domain.basic.Location;
import com.wzdigit.wms.basic.domain.basic.Sku;
import com.wzdigit.wms.basic.domain.inventory.Goods;
import com.wzdigit.wms.basic.domain.inventory.InvLoc;
import com.wzdigit.wms.basic.enums.inventory.count.approve.InvAprResultEnum;
import com.wzdigit.wms.basic.enums.inventory.count.dtl.InvDtlStatusEnum;
import com.wzdigit.wms.basic.enums.inventory.count.dtl.InvIsReplayEnum;
import com.wzdigit.wms.basic.enums.inventory.count.dtl.InvTaskTypeEnum;
import com.wzdigit.wms.basic.enums.inventory.count.goods.InvIsExitEnum;
import com.wzdigit.wms.basic.enums.inventory.count.header.*;
import com.wzdigit.wms.basic.mapper.core.basic.SkuMapper;
import com.wzdigit.wms.basic.mapper.core.inventory.GoodsMapper;
import com.wzdigit.wms.basic.mapper.core.inventory.InvLocMapper;
import com.wzdigit.wms.basic.util.HttpSessionUtil;
import com.wzdigit.wms.wms.client.response.inv.count.dto.InvLocDto;
import com.wzdigit.wms.wms.client.response.inv.count.dto.InvScopeDto;
import com.wzdigit.wms.wms.domain.inv.count.InvCountDtl;
import com.wzdigit.wms.wms.domain.inv.count.InvCountDtlGoods;
import com.wzdigit.wms.wms.domain.inv.count.InvCountHeader;
import com.wzdigit.wms.wms.domain.inv.count.InvCountScope;
import com.wzdigit.wms.wms.mapper.inv.count.InvCountDtlGoodsMapper;
import com.wzdigit.wms.wms.mapper.inv.count.InvCountDtlMapper;
import com.wzdigit.wms.wms.mapper.inv.count.InvCountHeaderMapper;
import com.wzdigit.wms.wms.mapper.inv.count.InvCountScopeMapper;
import com.wzdigit.wms.wms.service.inv.count.util.InvStarUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 盘点任务生成
 * Created by zyf on 2021/10/14 8:36
 */
@Slf4j
@Service
public class InvCountTaskService {
    @Autowired
    private InvCountHeaderMapper headerMapper;
    @Autowired
    private InvCountScopeMapper scopeMapper;
    @Autowired
    private InvCountDtlMapper dtlMapper;
    @Autowired
    private InvCountDtlGoodsMapper dtlGoodsMapper;
    @Autowired
    private GoodsMapper goodsMapper;
    @Autowired
    private SkuMapper skuMapper;

    @Autowired
    private InvStarUtil starUtil;

    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public Result<String> createCountTask(List<BigDecimal> headerIdList, HttpServletRequest servletRequest) throws Exception{

        Date nowDate=new Date();
        String loginName= HttpSessionUtil.getLoginName(servletRequest);

        for (BigDecimal headerId : headerIdList) {
            log.info("["+headerId+"]生成初盘任务");
            //对应库存记录集合
            List<InvLocDto> allInvLoc=new ArrayList<>();

            InvCountHeader header = headerMapper.
                    selectOne(new QueryWrapper<InvCountHeader>().eq("INV_COUNT_HEADER_ID",headerId));
            if (!header.getStatus().equals(InvHeaderStatusEnum.APPROVED.code)){
                Shift.fatal("仅["+InvHeaderStatusEnum.APPROVED.enumName+"]才能生成盘点任务!");
            }
           /* if (header.getApproveResult()==null){
                Shift.fatal("["+header.getInvCountNo()+"]未审核通过!");
            }*/
/*            if (header.getDynamicInventory()!=null){
                if (header.getDynamicInventory().equals(InvIsDynamicEnum.YES.code)){
                    Shift.fatal("["+header.getInvCountNo()+"]+为动态库存，无法生成任务!");
                }
            }*/
/*            if (!header.getApproveResult().equals(InvAprResultEnum.PASS.code)){
                Shift.fatal("["+header.getInvCountNo()+"]未审核通过!");
            }*/
            List<InvCountScope> scopeList = scopeMapper.selectList
                    (new QueryWrapper<InvCountScope>().eq("INV_COUNT_HEADER_ID",headerId));
            if (CollectionUtil.isEmpty(scopeList)){
                Shift.fatal("["+header.getInvCountNo()+"]未选择盘点范围!");
            }
            //是否包含空库位
            Boolean emptyFlag=true;
            if (header.getIncludeEmpty()!=null){
                if (header.getIncludeEmpty().equals(InvIsEmptyEnum.YES.code)){
                    emptyFlag=false;
                }
            }
            //是否包含待上架库位
            Boolean putFlag=false;
            if (header.getIncludeNoPutaway()!=null){
                if (header.getIncludeNoPutaway().equals(InvIsPutEnum.YES.code)){
                    putFlag=true;
                }
            }
            //是否置空批次号【目前仅当细度为按物料】
            Boolean gruFlag = header.getCountGranularity().equals(InvGranularityEnum.SKU_GRAN.code);
            for (InvCountScope scope : scopeList) {
                //获取盘点信息
                InvScopeDto invScopeDto = starUtil.searchScope(scope, header.getWhsId(), emptyFlag, putFlag);
                if (invScopeDto.getLocIds()!=null&&invScopeDto.getLocIds().size()>0){
                    List<InvLocDto> invLocDtos = headerMapper.selectLocByScope(invScopeDto.getLocIds(),invScopeDto.getLotnos() ,
                            invScopeDto.getSkuIds(), header.getWhsId(), emptyFlag, putFlag,gruFlag);
                    allInvLoc.addAll(invLocDtos);
                }
                else {
                    if (putFlag=false){
                        Shift.fatal("查无对应库存记录!");
                    }
                    List<InvLocDto> invLocDtos = headerMapper.selectLocByScopeNew(invScopeDto.getLocIds(),invScopeDto.getLotnos() ,
                            invScopeDto.getSkuIds(), header.getWhsId(), emptyFlag, putFlag,gruFlag);
                    allInvLoc.addAll(invLocDtos);
                }
            }
//            System.out.println(allInvLoc.size()+"000000000000");

            if (CollectionUtil.isEmpty(allInvLoc)){
                Shift.fatal("["+header.getInvCountNo()+"]查无对应库存信息!");
            }
            //生成盘点任务
            Map<BigDecimal, List<InvLocDto>> invMap =
                    allInvLoc.stream().collect(Collectors.groupingBy(InvLocDto::getInvLodId));
//            int dtlCount=0;//如果为0表示查无对应记录
            int i=1;
            for (Map.Entry<BigDecimal, List<InvLocDto>> map : invMap.entrySet()) {
                InvLocDto invLocDto = map.getValue().get(0);
                //查询是否存在相同的仓库为完成的盘点任务
                dtlMapper.selectNotCloseDtl(invLocDto);
                //生成盘点任务明细
                InvCountDtl dtl=new InvCountDtl();
                dtl.setInvCountHeaderId(headerId);
                dtl.setInvCountLineNo(i);
                dtl.setTaskType(InvTaskTypeEnum.ONCE_COUNT.code);
                dtl.setFactory(invLocDto.getFactory());
                dtl.setSkuId(invLocDto.getSkuId());
                dtl.setVendor(invLocDto.getVendor());
                dtl.setInvAttr(invLocDto.getInvAttr());
                dtl.setQaStatus(invLocDto.getQaStatus());
                dtl.setLotno(invLocDto.getLotno());
                dtl.setWhsId(invLocDto.getWhsId());
                dtl.setZoneId(invLocDto.getZoneId());
                dtl.setLocId(invLocDto.getLocId());
                dtl.setAccountQty(invLocDto.getQty());
                dtl.setCountQty(BigDecimal.ZERO);
                dtl.setReCount(InvIsReplayEnum.NO.code);
                dtl.setReCountId(BigDecimal.ZERO);
                Sku sku = skuMapper.selectOne(new QueryWrapper<Sku>().eq("SKU_ID", invLocDto.getSkuId()));
                dtl.setUnit(sku.getBaseUnit());
                dtl.setStatus(InvDtlStatusEnum.CREATE.code);
                dtl.setCreateUser(loginName);
                dtl.setCreateTime(nowDate);
                dtlMapper.insert(dtl);
                //如果有对应的SN则生成盘点GOODS
                QueryWrapper<Goods> goodsQuery=new QueryWrapper<Goods>();
                goodsQuery.eq("WHS_ID",invLocDto.getWhsId())
                .eq("SKU_ID",invLocDto.getSkuId())
                .eq("QA_STATUS",invLocDto.getQaStatus());
                if (invLocDto.getLotno()!=null){
                    goodsQuery.eq("LOTNO",invLocDto.getLotno());
                }else {
                    goodsQuery.isNull("LOTNO");
                }
                if (invLocDto.getFactory()!=null){
                    goodsQuery.eq("FACTORY",invLocDto.getFactory());
                }else {
                    goodsQuery.isNull("FACTORY");
                }
                if (invLocDto.getVendor()!=null){
                    goodsQuery.eq("VENDOR_ID",invLocDto.getVendor());
                }else {
                    goodsQuery.isNull("VENDOR_ID");
                }
                if (invLocDto.getLotno()!=null){
                    goodsQuery.eq("LOTNO",invLocDto.getLotno());
                }else {
                    goodsQuery.isNull("LOTNO");
                }
                if (invLocDto.getLocId()!=null){
                    goodsQuery.eq("LOC_ID",invLocDto.getLocId());
                }else {
                    goodsQuery.isNull("LOC_ID");
                }
                List<Goods> goodsList = goodsMapper.selectList(goodsQuery);
                if (!CollectionUtil.isEmpty(goodsList)){
                    for (Goods goods : goodsList) {
                        InvCountDtlGoods dtlGoods=new InvCountDtlGoods();
                        dtlGoods.setInvCountDtlId(dtl.getInvCountDtlId());
                        dtlGoods.setGoodsSn(goods.getGoodsSn());
                        dtlGoods.setGoodsId(new BigDecimal(goods.getGoodsId()));
                        dtlGoods.setAccountQty(goods.getQty());
                        dtlGoods.setCountQty(BigDecimal.ZERO);
                        dtlGoods.setAccountLoc(goods.getLocId());
                        dtlGoods.setCountLoc(goods.getLocId());
                        dtlGoods.setIsExist(InvIsExitEnum.NO.code);
                        dtlGoods.setStatus(goods.getStatus());
                        dtlGoods.setCreateUser(loginName);
                        dtlGoods.setCreateTime(nowDate);
                        dtlGoodsMapper.insert(dtlGoods);
                    }
                }
                i++;
            }
            //更新主档状态
            headerMapper.updateHeaderStatus(loginName, InvHeaderStatusEnum.WAIT_INV.code, Arrays.asList(headerId));
        }
        //Shift.fatal("//////////////");
        return new Result<>("生成盘点任务成功!");
    }

}
